
#include "tk.h"
#include "rcc.h"

/**
  * @brief  Deinitializes the TKx peripheral registers to their default reset values.
  * @param  TKx: where x can be 0 to select the TKx peripheral.
  * @retval None
  */
void TK_DeInit(TK_TypeDef* TKx)
{
	if(TKx == TK)
	{
		RCC_APB1PeriphResetCmd(RCC_APB1Periph_TK,ENABLE);
		RCC_APB1PeriphResetCmd(RCC_APB1Periph_TK,DISABLE);
	}
}

/**
  * @brief  Initializes the TK Base Unit peripheral according to 
  *         the specified parameters in the TK_InitStructure.
  * @param  TKx: where x can be 0 to 1 to select the TK peripheral.
  * @param  TK_InitStructure: pointer to a TK_InitTypeDef
  *         structure that contains the configuration information for the 
  *         specified TK peripheral.
  * @retval None
  */
void TK_Init(TK_TypeDef* TKx,TK_InitTypeDef* TK_InitStructure)
{
	uint16_t	tkcon_reg = 0;
	uint16_t	tkmts_reg = 0;
	uint16_t	tkchx_reg = 0;
	
	tkcon_reg = TKx->TKCON;
	//VRS
	tkcon_reg &= ~TK_TKCON_VRS_Level_Mask;
	tkcon_reg |= TK_InitStructure->VDS&TK_TKCON_VRS_Level_Mask;
	tkcon_reg &= ~(1<<3);
	tkcon_reg &= ~(1<<4);
	
	//TMEN
	tkcon_reg &= ~TK_TKCON_TMEN_Mask;
	tkcon_reg |= TK_InitStructure->TMEN;
	//CKD_DIV
	tkcon_reg &= ~TK_CKD_DIV_Mask;
	tkcon_reg |= TK_InitStructure->TK_ClockDivision&TK_CKD_DIV_Mask;
	//TKTMS
	tkcon_reg &= ~TK_TKCON_TKTMS_Mask;
	tkcon_reg |= (TK_InitStructure->TK_TMS<<8)&TK_TKCON_TKTMS_Mask;
	
	//TKMTS
	tkmts_reg = TKx->TKMTS;
	tkmts_reg &= ~TK_TKMTS_Mask;
	tkmts_reg |= TK_InitStructure->TKMTS&TK_TKMTS_Mask;
	//TKCVS
	tkmts_reg &= ~TK_TKMTS_TKCVS_Mask;
	tkmts_reg |= TK_InitStructure->TKCVS&TK_TKMTS_TKCVS_Mask;
	//TKPWS
	tkmts_reg &= ~TK_TKMTS_TKPWS_Mask;
	tkmts_reg |= TK_InitStructure->TKPWS&TK_TKMTS_TKPWS_Mask;	
	//TKVIRS
	tkmts_reg &= ~TK_TKMTS_VIRS_Mask;
	tkmts_reg |= TK_InitStructure->VIRS&TK_TKMTS_VIRS_Mask;	
	//TKVDS
	tkmts_reg &= ~TK_TKMTS_VDS_Mask;
	tkmts_reg |= TK_InitStructure->VDS&TK_TKMTS_VDS_Mask;		
	//TKPWC
	tkmts_reg &= ~TK_TKMTS_TKPWC_Mask;
	tkmts_reg |= TK_InitStructure->TKPWC&TK_TKMTS_TKPWC_Mask;		
	
	
	TKx->TKCON = tkcon_reg;
	TKx->TKMTS = tkmts_reg;
	
	
	if(TK_InitStructure->TK_CHSelInn == TK_CHSELINN_0)
	{
		tkchx_reg = TKx->TKCH01;
		tkchx_reg &= ~TK_CHSELINN_Low_Mask;
		tkchx_reg |= (TK_InitStructure->TK_Channel<<0)&TK_CHSELINN_Low_Mask;
		TKx->TKCH01 = tkchx_reg;
	}
	else if(TK_InitStructure->TK_CHSelInn == TK_CHSELINN_1)
	{
		tkchx_reg = TKx->TKCH01;
		tkchx_reg &= ~TK_CHSELINN_High_Mask;
		tkchx_reg |= (TK_InitStructure->TK_Channel<<8)&TK_CHSELINN_High_Mask;	
		TKx->TKCH01 = tkchx_reg;
	}
	else if(TK_InitStructure->TK_CHSelInn == TK_CHSELINN_2)
	{
		tkchx_reg = TKx->TKCH23;
		tkchx_reg &= ~TK_CHSELINN_Low_Mask;
		tkchx_reg |= (TK_InitStructure->TK_Channel<<0)&TK_CHSELINN_Low_Mask;		
		TKx->TKCH23 = tkchx_reg;
	}
	else if(TK_InitStructure->TK_CHSelInn == TK_CHSELINN_3)
	{
		tkchx_reg = TKx->TKCH23;
		tkchx_reg &= ~TK_CHSELINN_High_Mask;
		tkchx_reg |= (TK_InitStructure->TK_Channel<<8)&TK_CHSELINN_High_Mask;
		TKx->TKCH23 = tkchx_reg;
	}
	else if(TK_InitStructure->TK_CHSelInn == TK_CHSELINN_4)
	{
		tkchx_reg = TKx->TKCH45;
		tkchx_reg &= ~TK_CHSELINN_Low_Mask;
		tkchx_reg |= (TK_InitStructure->TK_Channel<<0)&TK_CHSELINN_Low_Mask;		
		TKx->TKCH45 = tkchx_reg;
	}
	else if(TK_InitStructure->TK_CHSelInn == TK_CHSELINN_5)
	{
		tkchx_reg = TKx->TKCH45;
		tkchx_reg &= ~TK_CHSELINN_High_Mask;
		tkchx_reg |= (TK_InitStructure->TK_Channel<<8)&TK_CHSELINN_High_Mask;
		TKx->TKCH45 = tkchx_reg;
	}	
}

/**
  * @brief  Enables or disables the specified TK peripheral.
  * @param  NewState: new state of the TK peripheral.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void TK_Cmd(TK_TypeDef* TKx,FunctionalState NewState)
{	
	if (NewState != DISABLE)
	{
		TKx->TKCON |= TK_TKCON_TKST;
	}
	else
	{
		TKx->TKCON &= ~TK_TKCON_TKST;
	}	
}

/**
  * @brief  Start the specified TK peripheral.
  * @retval None
  */
void TK_Start(TK_TypeDef* TKx)
{	
	TKx->TKCON |= TK_TKCON_TKST;
}

/**
  * @brief  Enables or disables the specified TK interrupts.
  * @param  TKx: where x can be 0  select the TK peripheral.   
  * @param  NewState: new state of the TK interrupts.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void TK_ITConfig(TK_TypeDef* TKx,FunctionalState NewState)
{
	if (NewState != DISABLE)
	{
		TKx->TKCON |= TK_TKCON_TKIE;
	}		
	else
	{
		TKx->TKCON &= ~TK_TKCON_TKIE;
	}
	
}


/**
  * @brief  Gets the TKx Prescaler value.
  * @retval Prescaler Register value.
  */
uint16_t TK_GetPrescaler(TK_TypeDef* TKx)
{
	return (uint16_t)(TKx->TKCON&TK_CKD_DIV_Mask);
}
/**
  * @brief  Set the TKx Prescaler value.
	*	@param  TK_CKD_DIVx: specifies the TK Clock div to set.
  *   This parameter can be one of the following values:
	*		TK_CKD_DIV1 ~~ TK_CKD_DIV8
  * @retval None
  */
void TK_SetPrescaler(TK_TypeDef* TKx,uint16_t TK_CKD_DIVx)
{
	uint16_t tkcon_reg = 0;
	tkcon_reg = TKx->TKCON;
	tkcon_reg &= ~TK_CKD_DIV_Mask;
	tkcon_reg |= TK_CKD_DIVx&TK_CKD_DIV_Mask;
	TKx->TKCON = tkcon_reg;
}

/*TKMF*/
/**
  * @brief  Checks whether the specified TK flag is set or not.
  * @param  TKx: where x can be 0 to 1 to select the TK peripheral.
  * @param  TK_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg TK_FLAG_TKIF0: TKMS0 Complete Flag
  *     @arg TK_FLAG_TKIF1: TKMS1 Complete Flag
  *     @arg TK_FLAG_TKIF2: TKMS2 Complete Flag
  *     @arg TK_FLAG_TKIF3: TKMS3 Complete Flag
  *     @arg TK_FLAG_TKIF4: TKMS4 Complete Flag
  *     @arg TK_FLAG_TKIF5: TKMS5 Complete Flag
  * @note
    
  * @retval The new state of TK_FLAG (SET or RESET).
  */
FlagStatus TK_GetFlagStatus(TK_TypeDef* TKx, uint16_t TK_FLAG)
{
  ITStatus bitstatus = RESET;  
  
  if ((TKx->TKIF & TK_FLAG) != (uint16_t)RESET)
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;	
}

/**
  * @brief  Checks whether the specified TK flag is set or not.
  * @param  TKx: where x can be 0 to 1 to select the TK peripheral.
  * @param  TK_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg TK_FLAG_TKIF0: TKMS0 Complete Flag
  *     @arg TK_FLAG_TKIF1: TKMS1 Complete Flag
  *     @arg TK_FLAG_TKIF2: TKMS2 Complete Flag
  *     @arg TK_FLAG_TKIF3: TKMS3 Complete Flag
  *     @arg TK_FLAG_TKIF4: TKMS4 Complete Flag
  *     @arg TK_FLAG_TKIF5: TKMS5 Complete Flag
  * @note  
  * @retval None
  */
void TK_ClearFlag(TK_TypeDef* TKx, uint16_t TK_FLAG)
{
  
  /* Clear the flags */
  TKx->TKIF = (uint16_t)TK_FLAG;	
}

/**
  * @brief  Checks whether the specified TK flag is set or not.
  * @param  TKx: where x can be 0 to 1 to select the TK peripheral.
  * @param  TK_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg TK_IT_TKIF0: TKMS0 Interrupt source
  *     @arg TK_IT_TKIF1: TKMS1 Interrupt source
  *     @arg TK_IT_TKIF2: TKMS2 Interrupt source
  *     @arg TK_IT_TKIF3: TKMS3 Interrupt source
  *     @arg TK_IT_TKIF4: TKMS4 Interrupt source
  *     @arg TK_IT_TKIF5: TKMS5 Interrupt source
  * @note
    
  * @retval The new state of TK_FLAG (SET or RESET).
  */
ITStatus TK_GetITStatus(TK_TypeDef* TKx, uint16_t TK_IT)
{
  ITStatus bitstatus = RESET;  
  uint16_t itstatus = 0x0;
   
  itstatus = TKx->TKIF & TK_IT;
  
  if ((itstatus != (uint16_t)RESET))
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;	
}

/**
  * @brief  Checks whether the specified TK flag is set or not.
  * @param  TKx: where x can be 0 to 1 to select the TK peripheral.
  * @param  TK_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg TK_IT_TKIF0: TKMS0 Interrupt source
  *     @arg TK_IT_TKIF1: TKMS1 Interrupt source
  *     @arg TK_IT_TKIF2: TKMS2 Interrupt source
  *     @arg TK_IT_TKIF3: TKMS3 Interrupt source
  *     @arg TK_IT_TKIF4: TKMS4 Interrupt source
  *     @arg TK_IT_TKIF5: TKMS5 Interrupt source
  * @note    
  * @retval None
  */
void TK_ClearITPendingBit(TK_TypeDef* TKx, uint16_t TK_IT)
{
  /* Clear the IT pending Bit */
  TKx->TKIF = (uint16_t)TK_IT;	

}


/**
  * @brief  Checks whether the specified TK flag is set or not.
  * @param  TKx: where x can be 0 to select the TK peripheral.
  * @param  TK_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg TK_CHSELINN_0: Select Ch0
  *     @arg TK_CHSELINN_1: Select Ch1
  *     @arg TK_CHSELINN_2: Select Ch2
  *     @arg TK_CHSELINN_3: Select Ch3
  *     @arg TK_CHSELINN_4: Select Ch4
  *     @arg TK_CHSELINN_5: Select Ch5

  * @note
    
  * @retval The TK_CH data.
  */
uint16_t TK_GetData(TK_TypeDef* TKx,uint16_t TK_CHSELINNx)
{
	uint16_t chxdata = 0x0;
	if(TK_CHSELINNx == TK_CHSELINN_0)
	{
		chxdata = (uint16_t)TKx->TKMS0;
	}
	else if(TK_CHSELINNx == TK_CHSELINN_1)
	{
		chxdata = (uint16_t)TKx->TKMS1;
	}	
	else if(TK_CHSELINNx == TK_CHSELINN_2)
	{
		chxdata = (uint16_t)TKx->TKMS2;
	}	
	else if(TK_CHSELINNx == TK_CHSELINN_3)
	{
		chxdata = (uint16_t)TKx->TKMS3;
	}	
	else if(TK_CHSELINNx == TK_CHSELINN_4)
	{
		chxdata = (uint16_t)TKx->TKMS4;
	}	
	else if(TK_CHSELINNx == TK_CHSELINN_5)
	{
		chxdata = (uint16_t)TKx->TKMS5;
	}		
	
	return (uint16_t)chxdata;
}


/**
  * @brief  Set the TKx TK_Clock Source.
  * @param  TKx: where x can be 0  to select the TK peripheral.
  * @param  TK_ClockSourcex: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg TK_ClockSource_HSI: Select HSI
  *     @arg TK_ClockSource_LSI: Select LSI
  * @note    
  * @retval None
  */

void TK_ClockSourceSet(TK_TypeDef* TKx,uint16_t TK_ClockSourcex)
{
	uint16_t	tkcon_reg = 0;
	tkcon_reg = TKx->TKCON;
	if(TK_ClockSourcex == TK_ClockSource_HSI)
	{
		tkcon_reg &= ~TK_ClockSource_HSI;
	}
	else if(TK_ClockSourcex == TK_ClockSource_LSI)
	{
		tkcon_reg &= ~TK_ClockSource_HSI;
		tkcon_reg |= TK_ClockSource_LSI;
	}
	TKx->TKCON = tkcon_reg;
}

/**
  * @brief  Config the TKx TK_Channelx Remap TK_CHSELINNx  Source.
  * @param  TKx: where x can be 0  to select the TK peripheral.
  * @param  TK_CHSELINNx: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg TK_CHSELINN_0: Select INN CH0
  *     @arg TK_CHSELINN_1: Select INN CH1
  *     @arg TK_CHSELINN_2: Select INN CH2
  *     @arg TK_CHSELINN_3: Select INN CH3
  *     @arg TK_CHSELINN_4: Select INN CH4
  *     @arg TK_CHSELINN_5: Select INN CH5
  * @param  TK_Channelx: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg TK_Channel_NULL,TK_Channel_TK0 ~~ TK_Channel_TK23,TK_Channel_TK_INN.
  * @note    
  * @retval None
  */
void TK_ChannelConfig(TK_TypeDef* TKx,uint16_t TK_CHSELINNx,uint16_t TK_Channelx)
{
	uint16_t tkchx_reg = 0;
	if(TK_CHSELINNx == TK_CHSELINN_0)
	{
		tkchx_reg = TKx->TKCH01;
		tkchx_reg &= ~TK_CHSELINN_Low_Mask;
		tkchx_reg |= (TK_Channelx<<0)&TK_CHSELINN_Low_Mask;
		TKx->TKCH01 = tkchx_reg;
	}
	else if(TK_CHSELINNx == TK_CHSELINN_1)
	{
		tkchx_reg = TKx->TKCH01;
		tkchx_reg &= ~TK_CHSELINN_High_Mask;
		tkchx_reg |= (TK_Channelx<<8)&TK_CHSELINN_High_Mask;	
		TKx->TKCH01 = tkchx_reg;
	}
	else if(TK_CHSELINNx == TK_CHSELINN_2)
	{
		tkchx_reg = TKx->TKCH23;
		tkchx_reg &= ~TK_CHSELINN_Low_Mask;
		tkchx_reg |= (TK_Channelx<<0)&TK_CHSELINN_Low_Mask;		
		TKx->TKCH23 = tkchx_reg;
	}
	else if(TK_CHSELINNx == TK_CHSELINN_3)
	{
		tkchx_reg = TKx->TKCH23;
		tkchx_reg &= ~TK_CHSELINN_High_Mask;
		tkchx_reg |= (TK_Channelx<<8)&TK_CHSELINN_High_Mask;
		TKx->TKCH23 = tkchx_reg;
	}
	else if(TK_CHSELINNx == TK_CHSELINN_4)
	{
		tkchx_reg = TKx->TKCH45;
		tkchx_reg &= ~TK_CHSELINN_Low_Mask;
		tkchx_reg |= (TK_Channelx<<0)&TK_CHSELINN_Low_Mask;		
		TKx->TKCH45 = tkchx_reg;
	}
	else if(TK_CHSELINNx == TK_CHSELINN_5)
	{
		tkchx_reg = TKx->TKCH45;
		tkchx_reg &= ~TK_CHSELINN_High_Mask;
		tkchx_reg |= (TK_Channelx<<8)&TK_CHSELINN_High_Mask;
		TKx->TKCH45 = tkchx_reg;
	}		
}


